package flp.gui.view.ant;

import flp.solvers.IOptimizationMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

/**
 * Klasa nasluchujaca, odpowiedzialna za pobieranie aktualnych danych podczas
 * trwania optymalizacji a nastepnie zaznaczanie ich w odpowiednich strukturach.
 * 
 * @author Necro
 */
public class AntOptimizationListener extends Thread implements IOptimizationMonitor {

    /** Kwant czasu o jaki odlegle sa od siebie momenty zaznaczania zebranych danych. */
    public static final int TIMESTEP = 300;
    
    /** Handler ktory stworzyl ta instancje monitora. */
    AntSolverHandler parent;
    
    /** Timer obslugujacy zaznaczanie danych. */
    private Timer timer;
   
    /** Ilosc iteracji miedzy wyswietleniami */
    private int n;
    
    /** Czas jaki uplynal od poczatku obliczen - do zaznaczenia na osi x */
    private int timeElapsed;
    
    /** Flaga sygnalizujaca rozpoczecie optymalizacji */
    private boolean started;

    /** Licznik iteracji. */
    private int iter;
    
    /** Licznik iteracji nie wnoszacych poprawy. */
    private int noChange;
    
    /** Najlepszy koszt lokalnie.*/
    private int localBest;
    
    /** Najlepszy koszt globalnie.*/
    private int globalBest;

     /** Konstruktor listenera.
     * 
     * @param parent Handler dla obslugiwanej optymalizacji.
     */
    public AntOptimizationListener(AntSolverHandler parent) {
        this.parent = parent;
        this.started = false;
    }

    /**
     * Klasa odpowiedzialna za pobieranie danych
     * co okreslony kwant czasu.
     */    
    class TimeredDataCollector implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            if (n == 0) {
                return;
            }
            timeElapsed += TIMESTEP;
            parent.dataPanel.updateValues(iter, localBest, globalBest);
            parent.chart.markData(localBest, globalBest, timeElapsed);
            n = 0;
            localBest = 0;

            if (parent.finished) {
                timer.stop();
            }
        }
    }

    @Override
    public void run() {
        timer = new Timer(TIMESTEP, new TimeredDataCollector());
        timer.setDelay(TIMESTEP);
        timer.start();
    }

     /** 
     * Metoda wywolywana z ciala Solver.computeSolution
     * zbierajaca dane z kazdej iteracji by je potem wyswietlic na wykresie
     */
    public void markProgress(Object[] values) {
        iter = (Integer) values[0];
        noChange = (Integer) values[1];
        localBest = (Integer) values[2];
        globalBest = (Integer) values[3];
        
        n++;
    }

    /** 
     * Metoda wywolywana z ciala Solver.computeSolution
     * zbierajaca dane z kazdej iteracji by je potem wyswietlic na wykresie.
     * @deprecated Tylko dla potrzeb testowania.
     */
    public void markProgress(String bestCost) {
    //@todo do_nothing
    //System.err.println(bestCost);
    }
}
